import os, json, random, requests, re, datetime, time, cv2, io, pyautogui
from PIL import Image

browser_type = 'chrome'

class TikTokSlider:
    def __init__(self, username, password, url='https://compass.jinritemai.com/login?roleType=shop', platform=None, owner=None):
        self.username = username
        self.password = password
        self.url = url
        self.platform = platform
        self.owner = owner

    # 获取滑块验证图片写入本地
    def __get_catpcha(self, verifyBgUrl, verifyPointUrl):
        """
        获取滑块验证图片写入本地
        :param verifyBgUrl: 主图链接
        :param verifyPointUrl: 次图链接
        :return:
        """
        # 获取主图的二进制
        main_pic = requests.get(verifyBgUrl).content
        # 将主图二进制转成 字节
        main_image_data = io.BytesIO(main_pic)
        # 主图地址， 次图地址
        main_file_path = "main_photo.jpg"; second_file_path = "second_photo.png"
        # 主图保存
        self.__handle_segmentation_main_picture(main_image_data, main_file_path)
        # --------------------------------------------------------------------
        # 次图保存
        second_pic = requests.get(verifyPointUrl).content
        # 保存到本地
        with open(second_file_path, 'wb') as file: file.write(second_pic)
        # --------------------------------------------------------------------
        # 返回主图，次图 地址
        return main_file_path, second_file_path

    # 分割拼接图片
    def __handle_segmentation_main_picture(self, main_image_data, main_file_path):
        """
        分割主图，按照顺序拼接
        :param main_image_data: 主图的图片字节
        :param main_file_path: 主图保存地址
        :return:
        """
        # 打开原始图片
        original_image = Image.open(main_image_data)
        # 将RGBA模式转换为RGB模式
        rgb_image = original_image.convert('RGB')
        # 获取原始图片的宽度和高度
        width, height = rgb_image.size
        # 计算每个横列图片的宽度
        column_width = width // 6
        # 创建一个空白画布，大小与单个横列图片相同
        canvas_width, canvas_height = (column_width * 6, height)
        canvas = Image.new('RGB', (canvas_width, canvas_height))
        # 循环剪切和粘贴每个横列图片
        for i, index in enumerate([4, 0, 3, 5, 2, 1]):
            # 计算当前横列图片的位置
            left = index * column_width
            right = left + column_width
            # 剪切横列图片
            column_image = rgb_image.crop((left, 0, right, height))
            # 粘贴到画布上
            canvas.paste(column_image, (i * column_width, 0))
        # 保存合并后的图片
        canvas.save(main_file_path)
        # 关闭所有图片
        original_image.close()
        canvas.close()


    # 获取滑块最终需要移动到到坐标X位置
    def __get_target_slider_point_x(self, verifyBgUrl, verifyPointUrl):
        """
        获取滑块最终需要移动到到坐标X位置
        :param verifyBgUrl: 主图链接
        :param verifyPointUrl: 次图链接
        :return:
        """
        # 下载图片并返回保存路径
        main_file_path, second_file_path = self.__get_catpcha(verifyBgUrl, verifyPointUrl)
        # ------------------------------------------------------------------------------
        # 读取主图， 变成BRG格式来OpenCV处理
        main_img = cv2.imread(main_file_path)
        # 获取主图像的边缘，Canny（图，阈值，阈值）
        main_edge = cv2.Canny(main_img, 100, 200)
        # 颜色空间转换函数，cvtColor（图，要变成的格式）
        main_pic = cv2.cvtColor(main_edge, cv2.COLOR_GRAY2RGB)
        # ------------------------------------------------------------------------------
        # 读取次图， 变成BRG格式来OpenCV处理
        second_img = cv2.imread(second_file_path)
        # 获取图像的边缘，Canny（图，阈值，阈值）
        second_edge = cv2.Canny(second_img, 100, 200)
        # 颜色空间转换函数，cvtColor（图，要变成的格式）
        second_pic = cv2.cvtColor(second_edge, cv2.COLOR_GRAY2RGB)
        # -------------------------------------------------------------------------------
        # 缺口匹配
        res = cv2.matchTemplate(main_pic, second_pic, cv2.TM_CCOEFF_NORMED)
        # 寻找最优匹配
        min_val, max_val, min_loc, max_loc = cv2.minMaxLoc(res)
        # 读取背景图片
        main_back_img = Image.open(main_file_path)
        main_back_img_size = main_back_img.size
        # 根据图片真实与表面大小的比例进行缩放
        point_x = max_loc[0] * main_back_img_size[1] / main_back_img_size[0]
        return int(point_x) + 1
    

    # 移动滑块
    def __move_slider(self, x, y, total_distance):
        """
        获取滑块最终需要移动到到坐标X位置
        :param x: 滑块横坐标
        :param y: 滑块纵坐标
        :param total_distance: 滑块距离
        :return:
        """
        current_x, current_y = x + random.randint(5, 10), y + random.randint(5, 10)
        initial_position = (current_x, current_y)
        # 移动鼠标
        pyautogui.moveTo(initial_position)
        # 模拟鼠标点击拖动
        pyautogui.mouseDown() # 鼠标按下
        # 定义滑动距离 （像素）
        step_distance = int(random.randint(100, 500)/10) # 每次移动10-50像素
        num_steps = total_distance // step_distance
        for _ in range(num_steps):
            # 计算目标位置的x坐标
            target_x = current_x + step_distance
            # 使用moveTo函数将鼠标移动到目标位置
            pyautogui.moveTo(target_x, current_y, duration=random.randint(5,15)/10)
            # 更新当前鼠标位置
            current_x = target_x
        # 模拟释放鼠标左键
        pyautogui.mouseUp()

if __name__ == '__main__':
    tts = TikTokSlider()
    tts.__move_slider()